package app.itgungnir.compose.wan.utils

import app.itgungnir.compose.wan.api.Api
import app.itgungnir.compose.wan.api.WanApi
import kotlinx.coroutines.runBlocking
import okhttp3.Cookie
import okhttp3.Interceptor
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.internal.platform.Platform
import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory

private val logger = HttpLoggingInterceptor.Logger { message ->
    if (message.isEmpty()) {
        return@Logger
    }
    val segmentSize = 3 * 1024
    val length = message.length
    if (length <= segmentSize) {
        Platform.get().log(message, Platform.INFO, null)
    } else {
        var msg = message
        while (msg.length > segmentSize) {
            val logContent = msg.substring(0, segmentSize)
            msg = msg.replaceFirst(logContent, "")
            Platform.get().log(logContent, Platform.INFO, null)
        }
        Platform.get().log(msg, Platform.INFO, null)
    }
}

private val loggingInterceptor = HttpLoggingInterceptor(logger).apply {
    level = HttpLoggingInterceptor.Level.BODY
}

private val wanAndroidCookiesInterceptor = Interceptor { chain ->
    val request = chain.request()
    var newRequestBuilder: Request.Builder? = null
    val requestUrl = request.url
    val requestPath = requestUrl.toUrl().path
    if (request.header(Header.NEED_LOGIN_KEY) == "true") {
        LocalDataStore.localData.wanAndroidCookiesList.takeIf { it.isNotEmpty() }?.let {
            newRequestBuilder = request.newBuilder().apply {
                it.forEach { cookie ->
                    addHeader("Cookie", cookie)
                }
            }
        }
    }
    val response = chain.proceed(newRequestBuilder?.build() ?: request)
    if (requestPath == Api.Account.LOGIN || requestPath == Api.Account.REGISTER) {
        response.headers("Set-Cookie").takeIf { it.any { item -> item.contains("token_pass") } }?.let {
            runBlocking {
                LocalDataStore.updateLocalData { builder ->
                    builder.hasLogin = true
                    builder.clearWanAndroidCookies().addAllWanAndroidCookies(it)
                }
            }
        }
    }
    if (requestPath == Api.Account.LOGOUT) {
        val logoutSuccess = Cookie.parseAll(request.url, response.headers).any { it.expiresAt <= 10000 }
        if (logoutSuccess) {
            runBlocking {
                LocalDataStore.updateLocalData { builder ->
                    builder.clearHasLogin()
                    builder.clearWanAndroidCookies()
                    builder.clearUserInfo()
                    builder.clearCoinInfo()
                }
            }
        }
    }
    response
}

private val wanAndroidClient = OkHttpClient.Builder()
    .addNetworkInterceptor(loggingInterceptor)
    .addInterceptor(wanAndroidCookiesInterceptor)
    .build()

object Header {
    const val NEED_LOGIN_KEY = "wan_compose_custom_header_need_login"
    const val NEED_LOGIN = "$NEED_LOGIN_KEY: true"
}

val wanAndroidService: WanApi = Retrofit.Builder()
    .baseUrl("https://www.wanandroid.com")
    .client(wanAndroidClient)
    .addConverterFactory(GsonConverterFactory.create())
    .build()
    .create(WanApi::class.java)

data class WanPagingResponse<T : Any>(
    val curPage: Int = 0,
    val size: Int = 0,
    val total: Int = 0,
    val datas: List<T>? = null,
    val over: Boolean = false
)
